/*
 * @Author: wusd
 * @Date: 2022-05-19 15:27:59
 * @LastEditors: wusd
 * @LastEditTime: 2024-11-08 16:17:40
 * @Description:
 *
 */

import { AnyObj } from 'types/common'
import { REGS } from './validate.js'

/**
 * 基于默认对象，只对默认对象的参数进行合并
 * @param {*} defaultObj 默认对象
 * @param {*} targetObj 目标对象
 * 仅在默认对象属性不存在时覆盖
 */
export function mergeObject(defaultObj: AnyObj = {}, targetObj: AnyObj = {}) {
  for (const key in targetObj) {
    if (isNull(defaultObj[key])) {
      defaultObj[key] = isNull(defaultObj[key]) ? targetObj[key] : defaultObj[key]
    } else {
      if (typeof targetObj[key] === 'object' && !Array.isArray(targetObj[key])) {
        mergeObject(defaultObj[key], targetObj[key])
      }
    }
  }
}

/**
 * 简单对象合并，针对wform组件，只判断对象第一层级
 * @param {*} defaultObj 默认对象
 * @param {*} targetObj 目标对象
 * 仅在默认对象属性不存在时覆盖
 */
export function mergeSingleObject(defaultObj: AnyObj = {}, targetObj: AnyObj = {}) {
  for (const key in targetObj) {
    if (typeof targetObj[key] === 'object') {
      if (JSON.stringify(defaultObj[key]) !== JSON.stringify(targetObj[key])) {
        defaultObj[key] = targetObj[key]
      }
    } else {
      if (defaultObj[key] !== targetObj[key]) {
        defaultObj[key] = targetObj[key]
      }
    }
  }
}

/**
 * @description: 判断值是否为空,包括空[],{},'',不包括0
 * @param {any} str 所需判断的值
 * @return {Boolean} 是否为空
 */
export function isNull(str: any) {
  if (str === undefined || str === null || str === '') {
    return true
  } else if (Array.isArray(str) && str.length === 0) {
    return true
  } else if (typeof str === 'object' && Object.keys(str).length === 0) {
    return true
  }
  return false
}

/**
 * @description: 判断取值是否为空,包括空'',不包括0,[],{}
 * @param {any} str 所需判断的值
 * @return {Boolean} 是否为空
 */
export function valueIsNull(str: any) {
  if (str === undefined || str === null || str === '') {
    return true
  }
  return false
}

/**
 * 日期格式化
 * @param {*} time
 * @param {*} format
 * @returns
 */
export function parseTime(time: Date | number | string, format = 'yyyy-mm-dd hh:ii:ss') {
  if (!time) return ''
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (isNaN(Number(time))) {
      date = new Date(time)
    } else {
      //在IE或safari下 需要将 - 转换为 / 否则无法识别，后续可添加，暂时不添加此逻辑
      time = typeof time === 'string' ? parseInt(time) : time
      if (('' + time).length === 10) time = time * 1000
      date = new Date(time)
    }
  }
  const formatObj: AnyObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const timeStr = format.replace(/(y|m|d|h|i|s|a)+/gi, (result, key) => {
    let value = formatObj[key]
    if (key === 'a') {
      if (value === 0) return '日'
      return ['一', '二', '三', '四', '五', '六'][value - 1]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return timeStr
}

// 无树状结构数组转换树状节点方法
export function arrayToTree(treeArray: any[], idKey = 'id', pidKey = 'pid', childrenKey = 'children') {
  const r = []
  const tmpMap: any = {}
  treeArray = [...treeArray]

  for (let i = 0, l = treeArray.length; i < l; i++) {
    // 以每条数据的id作为obj的key值，数据作为value值存入到一个临时对象里面
    tmpMap[treeArray[i][idKey]] = treeArray[i]
  }

  for (let j = 0, l = treeArray.length; j < l; j++) {
    const key = tmpMap[treeArray[j][pidKey]]

    // 循环每一条数据的pid，假如这个临时对象有这个key值，就代表这个key对应的数据有children，需要Push进去
    if (key) {
      if (!key[childrenKey]) {
        key[childrenKey] = [treeArray[j]]
      } else {
        const obj: any = {}
        const bindArr = [...key[childrenKey], treeArray[j]].sort(item => item[childrenKey]).reverse()
        key[childrenKey] = bindArr.reduce((cur, next) => {
          obj[next[idKey]] ? '' : (obj[next[idKey]] = true && cur.push(next))
          return cur
        }, [])
      }
    } else {
      // 如果没有这个Key值，那就代表没有父级,直接放在最外层
      r.push(treeArray[j])
    }
  }
  return r
}

/**
 * 筛选出树形结构数据某一项
 * @param {*} data
 * @param {*} val
 * @param {*} key
 * @param {*} childrenKey
 * @returns
 */
export function findValByKey(data: any, val: any, key = 'id', childrenKey = 'children'): any {
  for (const i in data) {
    if (data[i][key] && data[i][key] === val) {
      return data[i]
    }
    if (data[i][childrenKey] && data[i][childrenKey].length) {
      const result = findValByKey(data[i][childrenKey], val, key, childrenKey)
      if (result !== undefined) return result
    }
  }
}

/**
 *
 * @param value 得到数据类型
 */
export function getType(value: any) {
  const type = Object.prototype.toString.call(value)
  return type.replace(/(\[)|(\])/g, '').split(' ')[1]
}

/**
 *
 * @param data 重置对象
 * @param ingorn 忽略项数组
 * @returns
 */
export function resetObject(data: AnyObj, ingorn = ['pageSize', 'pageNum']) {
  const obj: AnyObj = {}
  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      if (ingorn.includes(key)) {
        obj[key] = data[key]
        continue
      }
      switch (getType(data[key])) {
        case 'Array':
          obj[key] = []
          break
        case 'Object':
          obj[key] = {}
          break
        case 'Number':
          obj[key] = null
          break
        case 'Null':
          obj[key] = null
          break
        default:
          obj[key] = ''
      }
    }
  }
  return obj
}

export function fixShowValue(row: any, show: any) {
  if (typeof show === 'boolean') {
    return show
  }
  if (!show) {
    return true
  } else {
    return show(row)
  }
}

/**数组求和 */
export function arrSum(arr: AnyObj[], str = '-') {
  let bool = true
  arr.forEach(item => {
    if (!REGS.number.test(item) && !valueIsNull(item)) {
      bool = false
    }
  })

  let sum: any = 0
  if (bool) {
    sum = arr.reduce((prev, curr) => {
      const value = Number(curr)
      if (!isNaN(value)) {
        return Number(prev) + Number(curr)
      } else {
        return Number(prev)
      }
    }, 0)
  } else {
    sum = str
  }
  return sum
}
